//
//	File Name   :	OpenGLTexture2D.cpp
//	Description :	OpenGLTexture2D implementation file.
//	Author		:	William McVicar
//  Mail		:	mcvicar.william@gmail.com
//

//  Precompiled Header
#include "CommonDefines.h"
#ifdef OPENGL

//  Library Includes

//  External Includes
#include <gl\GL.h>
#include "OpenGLExtensions.h"
#include "OpenGLRenderer.h"

//  Local Includes
#include "TextureBase.h"

//  This includes
#include "OpenGLTexture2D.h"

//	Macros

//  Static Variables

//  Static Function Prototypes

//  Implementation

namespace Protein
{

Texture2D::Texture2D( TextureBase* base )
: m_textureBase( base )
{
	glGenTextures( 1, &m_textureID );
	glBindTexture( GL_TEXTURE_2D, m_textureID );

	const Image& image = base->image();

	if( image.isCompressedFormat( image.PixelFormat() ) )
	{
		GLenum dataFormat	  = OpenGLRenderer::getGLDataFormat( image.PixelFormat() );

		int width  = image.Width();
		int height = image.Height();
		int mipmap = image.MipMapCount() > 0 ? image.MipMapCount() : 1;
		int size   = 0;
		int offset = 0;
		int blocksize = image.getBytesPerBlock( image.PixelFormat() );

		for( int i = 0; i < mipmap; ++i )
		{
			if( width  == 0 ) width  = 1;
			if( height == 0 ) height = 1;

			size = ((width+3)/4) * ((height+3)/4) * blocksize;
			OpenGLExtensions::glCompressedTexImage2D( GL_TEXTURE_2D, i, dataFormat, width, height, 0, size, image.Data() + offset );
			offset += size;
			width  = (width>>1);
			height = (height>>1);
		}
	}
	else
	{
		GLenum internalFormat = OpenGLRenderer::getGLInternalFormat( image.PixelFormat() );
		GLenum dataFormat	  = OpenGLRenderer::getGLDataFormat( image.PixelFormat() );
		GLenum dataType		  = OpenGLRenderer::getGLDataType( image.PixelFormat() );
		glTexImage2D( GL_TEXTURE_2D, 0, internalFormat, image.Width(), image.Height(), 0, dataFormat, dataType, image.Data() );
	}

	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	glBindTexture  ( GL_TEXTURE_2D, NULL );
}

Texture2D::~Texture2D()
{
	delete m_textureBase;
	m_textureBase = NULL;
}

void Texture2D::Enable()
{
	glBindTexture(GL_TEXTURE_2D, m_textureID );
}

void Texture2D::Disable()
{
	glBindTexture(GL_TEXTURE_2D, NULL );
}

}

#endif